package com.xingfly.event.component;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

/**
 * Created by SuperS on 2019/11/19.
 *
 * @author SuperS
 */
@Aspect
@Component
public class RabbitDomainEventPublishAspect {

    private RabbitDomainEventPublish rabbitDomainEventPublish;

    private TaskExecutor taskExecutor;

    public RabbitDomainEventPublishAspect(RabbitDomainEventPublish rabbitDomainEventPublish) {
        this.rabbitDomainEventPublish = rabbitDomainEventPublish;
        this.taskExecutor = taskExecutor();
    }

    private TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(1);
        executor.setQueueCapacity(500);
        executor.setThreadNamePrefix("domain-event-publish-executor-");
        executor.initialize();
        return executor;
    }

    @After("@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.PutMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.PatchMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.DeleteMapping) ||" +
            "@annotation(org.springframework.amqp.rabbit.annotation.RabbitHandler) ||" +
            "@annotation(org.springframework.amqp.rabbit.annotation.RabbitListener)")
    public void publishEvents(JoinPoint joinPoint) {
        taskExecutor.execute(() -> rabbitDomainEventPublish.publishNextBatch());
    }

}
